import logging
from typing import Dict, Any

import plotly.graph_objects as go
from plotly.subplots import make_subplots

from 程序核心代码.ast节点.节点分析.可视化.可视化器基类 import 可视化器基类
from 程序核心代码.ast节点.节点定义.基础定义.节点异常定义 import 节点异常

logger = logging.getLogger(__name__)

class 性能分析可视化器(可视化器基类):
    """性能分析可视化器类，用于可视化性能分析结果"""
    
    def __init__(self):
        super().__init__()
        self.图表 = None
        self.颜色方案 = {
            "执行时间": "#2196F3",
            "内存使用": "#4CAF50",
            "时间复杂度": "#FF9800",
            "性能瓶颈": "#F44336"
        }
        
    def 可视化(self, 数据: Dict[str, Any]) -> str:
        """将性能分析数据可视化为交互式图表"""
        try:
            self.数据 = 数据
            self.图表 = make_subplots(
                rows=2, cols=2,
                subplot_titles=(
                    "执行时间分布",
                    "内存使用分布",
                    "时间复杂度分布",
                    "性能瓶颈分布"
                )
            )
            
            self._添加执行时间图表()
            self._添加内存使用图表()
            self._添加时间复杂度图表()
            self._添加性能瓶颈图表()
            self._更新布局()
            
            return self._生成HTML()
            
        except Exception as e:
            logger.error(f"性能分析可视化失败: {str(e)}")
            raise 节点异常(f"性能分析可视化失败: {str(e)}")
            
    def _添加执行时间图表(self) -> None:
        """添加执行时间分布图表"""
        执行时间数据 = self.数据.get("执行时间统计", {})
        节点IDs = list(执行时间数据.keys())
        执行时间 = list(执行时间数据.values())
        
        self.图表.add_trace(
            go.Bar(
                x=节点IDs,
                y=执行时间,
                name="执行时间",
                marker_color=self.颜色方案["执行时间"]
            ),
            row=1, col=1
        )
        
    def _添加内存使用图表(self) -> None:
        """添加内存使用分布图表"""
        内存使用数据 = self.数据.get("内存使用统计", {})
        节点IDs = list(内存使用数据.keys())
        内存使用 = list(内存使用数据.values())
        
        self.图表.add_trace(
            go.Bar(
                x=节点IDs,
                y=内存使用,
                name="内存使用",
                marker_color=self.颜色方案["内存使用"]
            ),
            row=1, col=2
        )
        
    def _添加时间复杂度图表(self) -> None:
        """添加时间复杂度分布图表"""
        复杂度数据 = self.数据.get("复杂度分布", {})
        复杂度类型 = list(set(复杂度数据.values()))
        复杂度计数 = {类型: list(复杂度数据.values()).count(类型) 
                   for 类型 in 复杂度类型}
        
        self.图表.add_trace(
            go.Pie(
                labels=list(复杂度计数.keys()),
                values=list(复杂度计数.values()),
                name="时间复杂度",
                marker_colors=[self.颜色方案["时间复杂度"]]
            ),
            row=2, col=1
        )
        
    def _添加性能瓶颈图表(self) -> None:
        """添加性能瓶颈分布图表"""
        瓶颈数据 = self.数据.get("性能瓶颈", [])
        瓶颈类型 = ["执行时间", "内存使用", "时间复杂度"]
        瓶颈计数 = {类型: len([x for x in 瓶颈数据 if x["类型"] == 类型])
                 for 类型 in 瓶颈类型}
        
        self.图表.add_trace(
            go.Pie(
                labels=list(瓶颈计数.keys()),
                values=list(瓶颈计数.values()),
                name="性能瓶颈",
                marker_colors=[self.颜色方案["性能瓶颈"]]
            ),
            row=2, col=2
        )
        
    def _更新布局(self) -> None:
        """更新图表布局"""
        self.图表.update_layout(
            height=800,
            showlegend=True,
            title_text="性能分析报告",
            title_x=0.5,
            title_font_size=20,
            paper_bgcolor="white",
            plot_bgcolor="rgba(0,0,0,0)"
        )
        
        # 更新x轴
        self.图表.update_xaxes(
            title_text="_节点ID",
            row=1, col=1
        )
        self.图表.update_xaxes(
            title_text="_节点ID",
            row=1, col=2
        )
        
        # 更新y轴
        self.图表.update_yaxes(
            title_text="执行时间 (秒)",
            row=1, col=1
        )
        self.图表.update_yaxes(
            title_text="内存使用 (字节)",
            row=1, col=2
        )
        
    def _生成HTML(self) -> str:
        """生成可视化HTML"""
        try:
            模板 = self.加载模板("性能分析")
            图表数据 = self.图表.to_html(
                full_html=False,
                include_plotlyjs=True,
                config={"responsive": True}
            )
            
            return 模板.replace(
                "<!-- CHART_PLACEHOLDER -->",
                图表数据
            )
            
        except Exception as e:
            logger.error(f"HTML生成失败: {str(e)}")
            raise 节点异常(f"HTML生成失败: {str(e)}")
            
    def 生成性能报告(self) -> str:
        """生成性能分析报告"""
        try:
            报告模板 = self.加载模板("性能报告")
            
            # 格式化性能数据
            执行时间统计 = self.数据.get("执行时间统计", {})
            内存使用统计 = self.数据.get("内存使用统计", {})
            性能瓶颈 = self.数据.get("性能瓶颈", [])
            
            报告数据 = {
                "总执行时间": f"{执行时间统计.get('总计', 0):.4f} 秒",
                "平均执行时间": f"{执行时间统计.get('平均', 0):.4f} 秒",
                "总内存使用": f"{内存使用统计.get('总计', 0) / 1024 / 1024:.2f} MB",
                "平均内存使用": f"{内存使用统计.get('平均', 0) / 1024 / 1024:.2f} MB",
                "性能瓶颈数": len(性能瓶颈),
                "瓶颈详情": [
                    {
                        "节点模型": 瓶颈["节点模型"],
                        "类型": 瓶颈["类型"],
                        "描述": 瓶颈["描述"],
                        "建议": self._生成优化建议(瓶颈)
                    }
                    for 瓶颈 in 性能瓶颈
                ]
            }
            
            return 报告模板.format(**报告数据)
            
        except Exception as e:
            logger.error(f"性能报告生成失败: {str(e)}")
            raise 节点异常(f"性能报告生成失败: {str(e)}")
            
    def _生成优化建议(self, 瓶颈: Dict[str, Any]) -> str:
        """根据瓶颈类型生成优化建议"""
        if 瓶颈["类型"] == "执行时间":
            return "考虑使用缓存或优化算法实现"
        elif 瓶颈["类型"] == "内存使用":
            return "考虑使用生成器或减少中间结果存储"
        elif 瓶颈["��型"] == "时间复杂度":
            return "考虑使用更高效的算法或数据结构"
        return "需要进一步分析"
        
    def 重置(self) -> None:
        """重置可视化器状态"""
        super().清理数据()
        self.图表 = None 